<template>
  <div class="l-select-panel">
    <l-panel style="padding: 0">
      <template #toolLeft>
        <div class="l-panel--item" v-if="multiple">
          <el-radio-group
            v-model="showType"
            size="mini"
            @change="handleTypeChange"
          >
            <el-radio-button label="1">全部</el-radio-button>
            <el-radio-button label="2">已选</el-radio-button>
          </el-radio-group>
        </div>
        <div class="l-panel--item" v-if="showType == 1 || model == 'client'">
          <el-input
            :placeholder="$t('请输入查询关键字')"
            v-model="searchWord"
            size="mini"
            @clear="hanleSearchInput"
            @input="hanleSearchInput"
            @keyup.enter.native="hanleSearch"
          >
            <el-button
              slot="append"
              icon="el-icon-search"
              @click="hanleSearch"
            ></el-button>
          </el-input>
        </div>
        <div class="l-panel--item l-select-panel--numText" v-if="multiple">
          {{ `${$t("已经选中")}${value2.length}${$t("条")}` }}
        </div>
      </template>
      <template #toolRight>
        <el-button-group v-if="isRefresh">
          <el-button
            :disabled="disabledRefresh"
            size="mini"
            icon="el-icon-refresh-left"
            @click="handleRefresh"
          ></el-button>
        </el-button-group>
        <slot name="btns"></slot>
        <el-button-group v-if="multiple">
          <el-button
            type="danger"
            size="mini"
            icon="el-icon-delete"
            @click="handleClear()"
            >清空</el-button
          >
        </el-button-group>
      </template>
      <l-table
        :columns="columns"
        :dataSource="tableShowData"
        :loading="selectLoading"
        :isPage="isPage"
        :pageTotal="tableTotal"
        :tablePage.sync="tableCurrentPage"
        :isMultiSelect="multiple"
        :reserveSelection="false"
        :pageSizes="[20, 30, 50]"
        :pageSize="tablePageSize"
        :row-key="valueKey"
        :default-expand-all="defaultExpandAll"
        @select="handleSelect"
        @selectAll="handleSelectAll"
        @loadPageData="turnTablePage"
        @rowClick="handleRowClick"
        ref="selectTable"
      >
        <template v-for="item in columns" v-slot:[item.prop]="scope">
          <slot v-bind="scope" :name="item.prop"></slot>
        </template>
        <slot></slot>
      </l-table>
    </l-panel>
  </div>
</template>
<script>
import { validatenull } from "@util/validate";
export default {
  name: "l-select-panel",
  props: {
    value: {},
    valueKey: {
      type: String,
      default: "value",
    },
    idKey: {
      type: String,
    },
    pidKey: {
      type: String,
    },
    labelKey: {
      type: String,
    },

    columns: {
      type: Array,
      default: () => [],
    },
    model: {
      type: String,
      default: "service", // service（选中数据从后端加载） client （选中数据从前端获取）
    },
    selectedData: {
      // 当前选中的数据 只有 在 client模式下才起作用
      type: Array,
      default: () => [],
    },
    loadSelectTable: {
      type: Function,
    },
    refreshData: {
      type: Function,
    },
    isRefresh: {
      type: Boolean,
      default: false,
    },
    isPage: {
      type: Boolean,
      default: true,
    },
    isTree: {
      type: Boolean,
      default: false,
    },
    multiple: {
      type: Boolean,
      default: true,
    },
    defaultExpandAll: {
      type: Boolean,
      default: true,
    },
    isChangeSearch: {
      type: Boolean,
      default: false,
    },

    notSelectChildren: {
      type: Boolean,
      default: false,
    },
  },
  created() {},
  data() {
    return {
      searchWord: "",
      selectLoading: false,
      tableData: [],
      tableTotal: 0,
      tablePageSize: 20,
      tableCurrentPage: 1,
      showType: 1,
      disabledRefresh: false,
    };
  },
  mounted() {},
  computed: {
    value2: {
      get() {
        if (this.multiple) {
          if (!validatenull(this.value)) {
            return (this.value + "").split(",");
          } else {
            return [];
          }
        } else {
          return this.value;
        }
      },
      set(val) {
        if (this.multiple) {
          this.$emit("input", String(val));
        } else {
          this.$emit("input", val);
        }
        this.$emit("change", val);
      },
    },
    tableShowData() {
      if (this.isTree) {
        return this.$toTree(
          this.tableData,
          this.idKey,
          this.pidKey,
          this.valueKey,
          this.labelKey
        );
      } else {
        return this.tableData;
      }
    },
  },
  methods: {
    init() {
      this.tableLoadData();
    },
    reset() {
      this.showType = 1;
      this.value2 = [];
      this.searchWord = "";
      if (this.model == "client") {
        this.$emit("update:selectedData", []);
      }
      this.tableData = [];
    },
    hanleSearch() {
      this.tableLoadData();
    },
    hanleSearchInput() {
      if (this.isChangeSearch) {
        this.hanleSearch();
      }
    },

    handleSelect(selection, row) {
      //console.log(selection,row,'selection')
      if (this.isTree && row && !this.notSelectChildren) {
        //this.$nextTick(()=>{
        const sres = [];
        if (
          selection.findIndex((t) => t[this.valueKey] == row[this.valueKey]) !=
          -1
        ) {
          if (row.children && row.children.length > 0) {
            this.selectChildren(row.children, selection, sres, true);
          }

          selection.push(...sres);
        } else {
          if (row.children && row.children.length > 0) {
            this.selectChildren(row.children, selection, sres, false);
          }
          selection = selection.filter(
            (t) =>
              sres.findIndex((t2) => t2[this.valueKey] == t[this.valueKey]) ==
              -1
          );
        }
      }

      let valueTmp = this.value2;
      let selectedDataTmp = this.selectedData;

      // 获取当前选中的列
      let selectedList = selection.map((t) => t[this.valueKey]);
      //获取当前选中的列的对象

      // 获取增加项
      let addList = selectedList.filter((t) => valueTmp.indexOf(t) == -1);

      //console.log(addList,'addList')

      if (addList.length > 0) {
        valueTmp = addList.concat(valueTmp);
        if (this.model == "client") {
          selectedDataTmp = selectedDataTmp.concat(
            this.tableData.filter(
              (t) => addList.indexOf(t[this.valueKey]) != -1
            )
          );
        }
      } else {
        // 获取当前页面没有被选中的
        let notSelectedList = this.tableData
          .filter((t) => selectedList.indexOf(t[this.valueKey]) == -1)
          .map((t) => t[this.valueKey]);
        // 获取减少项
        let deleteList = notSelectedList.filter(
          (t) => valueTmp.indexOf(t) != -1
        );

        valueTmp = valueTmp.filter((t) => deleteList.indexOf(t) == -1);

        if (this.model == "client") {
          selectedDataTmp = selectedDataTmp.filter(
            (t) => deleteList.indexOf(t[this.valueKey]) == -1
          );
        }
      }

      this.value2 = valueTmp; // 赋值

      if (this.model == "client") {
        this.$emit("update:selectedData", selectedDataTmp);
      }
    },
    handleSelectAll(selection) {
      if (this.isTree) {
        if (this.tableData.length > 0) {
          let valueTmp = this.value2;
          if (
            this.tableData.filter(
              (t) => valueTmp.indexOf(t[this.valueKey]) != -1
            ).length < this.tableData.length
          ) {
            let needSelectData = this.tableData.map((t) => t[this.valueKey]);
            this.$nextTick(() => {
              this.selectTreeRows2(this.tableShowData, needSelectData);
            });
            this.handleSelect(this.tableData);
          } else {
            // 表示全部不选中
            this.$refs.selectTable.clearSelection();
            this.handleSelect([]);
          }
        }
      } else {
        this.handleSelect(selection);
      }
    },
    tableLoadData(isNotFirst) {
      if (!isNotFirst) {
        this.tableCurrentPage = 1;
      }
      this.selectLoading = true;
      let queryData = {
        rows: this.tablePageSize,
        page: this.tableCurrentPage,

        showType: this.showType,
      };

      if (this.showType == 2) {
        if (this.model == "client") {
          // 如果是客户端模式加载本地选中的数据
          this.loadClient();
          this.selectLoading = false;
          return;
        }

        // 显示选择数据
        let ids = this.value2;
        if (this.isPage) {
          ids = this.$pagination(
            this.tableCurrentPage,
            this.tablePageSize,
            this.value2
          );
        }
        if (ids.length == 0) {
          this.tableTotal = 0;
          this.tableData = [];
          this.selectLoading = false;
          return;
        }
        queryData.ids = String(ids);
      } else {
        queryData.keyword = this.searchWord;
      }

      if (this.loadSelectTable) {
        this.loadSelectTable(queryData)
          .then((res) => {
            const data = this.$deepClone(res);
            this.tableData = data.rows;
            if (this.showType == 1) {
              this.tableTotal = data.records;
            } else {
              this.tableTotal = this.value2.length;
            }

            this.selectLoading = false;
            this.disabledRefresh = false;
            if (this.multiple) {
              this.selectRows();
            }
          })
          .catch(() => {
            this.tableData = [];
            this.selectLoading = false;
            this.disabledRefresh = false;
          });
      } else {
        this.disabledRefresh = false;
        this.selectLoading = false;
      }
    },
    turnTablePage({ rows }) {
      this.tablePageSize = rows;
      this.tableLoadData(true);
    },
    loadClient() {
      let tableData = this.selectedData;

      if (!this.$validatenull(this.searchWord)) {
        tableData = tableData.filter((t) => this.clientFilter(t));
      }

      if (this.isPage) {
        this.tableData = this.$pagination(
          this.tableCurrentPage,
          this.tablePageSize,
          tableData
        );
        this.tableTotal = this.value2.length;
      } else {
        this.tableData = tableData;
      }

      this.selectRows();
    },
    selectRows() {
      this.$nextTick(() => {
        if (this.isTree) {
          this.selectTreeRows(this.tableShowData);
        } else {
          this.tableData.forEach((row) => {
            if (this.value2.indexOf(row[this.valueKey]) != -1) {
              this.$refs.selectTable.toggleRowSelection(row, true);
            }
          });
        }
      });
    },
    selectTreeRows(data) {
      data.forEach((row) => {
        if (this.value2.indexOf(row.value) != -1) {
          this.$refs.selectTable.toggleRowSelection(row, true);
        }
        if (row.children) {
          this.selectTreeRows(row.children);
        }
      });
    },
    selectTreeRows2(data, selectValues) {
      data.forEach((row) => {
        if (selectValues.indexOf(row.value) != -1) {
          this.$refs.selectTable.toggleRowSelection(row, true);
        }
        if (row.children) {
          this.selectTreeRows2(row.children, selectValues);
        }
      });
    },
    clientFilter(t) {
      for (let id in t) {
        let v = t[id] + "";
        if (v.indexOf(this.searchWord) != -1) {
          return true;
        }
      }
      return false;
    },

    handleClear() {
      this.value2 = [];
      this.searchWord = "";
      if (this.model == "client") {
        this.$emit("update:selectedData", []);
      }
      this.$refs.selectTable.clearSelection();
      this.showType = 1;
      this.tableLoadData();
    },
    handleTypeChange() {
      this.tableLoadData();
    },
    // 单选实现
    handleRowClick(row) {
      if (!this.multiple) {
        // 如果是单选才有效果
        this.$emit("update:selectedData", [row]);
        this.value2 = row[this.valueKey];
        this.$emit("rowClick", row);
      }
    },

    handleRefresh() {
      this.value2 = [];
      this.searchWord = "";
      if (this.model == "client") {
        this.$emit("update:selectedData", []);
      }
      this.$refs.selectTable.clearSelection();
      this.showType = 1;

      this.refreshData && this.refreshData();
      this.disabledRefresh = true;
    },

    selectChildren(list, selection, res, selected) {
      list.forEach((row) => {
        if (selected) {
          if (
            selection.findIndex(
              (t) => t[this.valueKey] == row[this.valueKey]
            ) == -1
          ) {
            this.$refs.selectTable.toggleRowSelection(row, true);
            res.push(row);
          }
          if (row.children && row.children.length > 0) {
            this.selectChildren(row.children, selection, res, true);
          }
        } else {
          if (
            selection.findIndex(
              (t) => t[this.valueKey] == row[this.valueKey]
            ) != -1
          ) {
            this.$refs.selectTable.toggleRowSelection(row, false);
            res.push(row);
          }
          if (row.children && row.children.length > 0) {
            this.selectChildren(row.children, selection, res, false);
          }
        }
      });
    },
  },
};
</script>
<style lang="less">
@import "./index.less";
</style>
